<template>
  <div id="ActiveXDivOne">
    <el-row :gutter="20">
      <el-col :xs="24" :sm="12" :md="8" :lg="6" :xl="6">
        <video id="camera-video"></video>
      </el-col>
      <el-col :xs="24" :sm="12" :md="8" :lg="4" :xl="4">
        <el-select v-model="type" placeholder="请选择拍照类型" v-if="isShowType" style="margin-bottom: 20px;">
          <el-option label="老人照片" value="avatar"></el-option>
          <el-option label="身份证正面" value="id_card_front"></el-option>
          <el-option label="身份证反面" value="id_card_back"></el-option>
        </el-select>
        <el-select v-model="camera" class="d2-mt-20" @change="handleChangeCamera" placeholder="请选择摄像头" style="margin-bottom: 20px;">
          <el-option
            v-for="item in devicesList"
            :key="item.deviceId"
            :label="item.label"
            :value="item.deviceId">
          </el-option>
        </el-select>
        <el-button type="primary" @click="captu" class="d2-mt-20 camera-button" style="width: 100%;">拍照并上传</el-button>
      </el-col>
      <el-col :xs="24" :sm="12" :md="8" :lg="12" :xl="12">
        <vue-cropper v-if="imgFile" ref="cropper" :imgFile="imgFile" @upload="upload"></vue-cropper>
      </el-col>
    </el-row>
    <canvas id="camera-canvas" width="1600" height="1200" style="display: none;"></canvas>
  </div>
</template>

<script>
import VueCropper from '@/components/camera-module/vue-cropper'
import { uploadCameraFilePromise } from '@/api/upload'
export default {
  name: 'camera-module',
  props: {
    isShowType: {
      type: Boolean,
      default: true
    }
  },
  components: {
    VueCropper
  },
  data () {
    return {
      // 摄像头设备
      devicesList: [],
      // 图片上传类型
      type: '',
      // 摄像头元素
      camera: '',
      stream: null,
      imgFile: ''
    }
  },
  mounted () {
    this.init()
  },
  methods: {
    // 首次加载
    init () {
      this.loadDevices()
      if (navigator.mediaDevices && navigator.mediaDevices.enumerateDevices) {
        const config = {
          video: {
            width: { min: 1600, ideal: 3264 },
            height: { min: 1200, ideal: 2448 },
            advanced: [
              { width: 1200, height: 900 },
              { aspectRatio: 1.333 }
            ]
          }
        }
        this.openCamera(config)
        const cameraVideo = document.getElementById('camera-video')
        const canvasObjs = document.getElementById('camera-canvas')
        const canvasObj = canvasObjs.getContext('2d')
        setInterval(() => {
          canvasObj.drawImage(cameraVideo, 0, 0, 1600, 1200)
        }, 15)
      }
    },
    // 裁剪上传
    upload (afterImg) {
      if (!this.type && this.isShowType) {
        this.$message.warning('请选择拍照类型')
        return false
      }
       uploadCameraFilePromise(afterImg).then(res => {
        // let img = URL.createObjectURL(afterImg);
        if(res.code == 200){
          this.$emit('upload', this.type, res.data)
        }
        this.imgFile = ''
        if (this.imgFile) {
          this.$refs.cropper.clearCrop()
        }
      })
    },
    // 拍照
    captu () {
      this.imgFile = ''
      if (this.imgFile) {
        this.$refs.cropper.clearCrop()
      }
      const _this = this
      setTimeout(() => {
        const canvasObj = document.getElementById('camera-canvas')
        const cameraVideo = document.getElementById('camera-video')
        const ctx = canvasObj.getContext('2d')
        const w = canvasObj.width
        const h = canvasObj.height
        ctx.clearRect(0, 0, w, h)
        ctx.drawImage(cameraVideo, 0, 0, 1600, 1200)
        const img = canvasObj.toDataURL()
        _this.imgFile = img
      }, 100)
    },
    // 切换摄像头
    handleChangeCamera (value) {
      if (this.stream) {
        this.stream.getTracks().forEach(track => {
          track.stop()
        })
      }
      const config = {
        video: {
          deviceId: value ? { exact: value } : undefined,
          width: { min: 1600, ideal: 3264 },
          height: { min: 1200, ideal: 2448 },
          advanced: [
            { width: 1200, height: 900 },
            { aspectRatio: 1.333 }
          ]
        }
      }
      this.openCamera(config)
    },
    // 调用成功的方法
    successObj (stream) {
      const cameraVideo = document.getElementById('camera-video')
      // 兼容webkit核心浏览器
      // let CompatibleURL = window.URL || window.webkitURL;
      // 将视频流设置为video元素的源
      console.log(stream)
      // video.src = CompatibleURL.createObjectURL(stream);
      // 将摄像头拍摄的视频赋值给viedeo的srcObject属性
      // src是视频文件,srcObject是实时流
      // 摄像头是实时流
      if ('srcObject' in cameraVideo) {
        cameraVideo.srcObject = stream
      } else {
        // 防止在新的浏览器里使用它，应为它已经不再支持了
        cameraVideo.src = window.URL.createObjectURL(stream)
      }
      this.stream = stream
      cameraVideo.onloadedmetadata = function (e) {
        cameraVideo.play()
      }
    },
    errorObj () {
      this.$message.warning('打开摄像头失败，请确定是否连接设备，并同意使用摄像头')
    },
    getUserMedia (constraints, success, error) {
      if (navigator.mediaDevices.getUserMedia) {
        // 最新的标准API
        navigator.mediaDevices.getUserMedia(constraints).then(success).catch(error)
      } else if (navigator.webkitGetUserMedia) {
        // webkit核心浏览器
        navigator.webkitGetUserMedia(constraints, success, error)
      } else if (navigator.mozGetUserMedia) {
        // firfox浏览器
        navigator.mozGetUserMedia(constraints, success, error)
      } else if (navigator.getUserMedia) {
        // 旧版API
        navigator.getUserMedia(constraints, success, error)
      }
    },
    // 打开摄像头
    openCamera (videoObj) {
      // 兼容性写法,判断getUserMedia方法是否存在
      navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia || navigator.msGetUserMedia || window.getUserMedia
      if (navigator.getUserMedia) {
        // 调用用户媒体设备, 访问摄像头
        this.getUserMedia(videoObj, this.successObj, this.errorObj)
      } else {
        this.$message.warning('请检测是否插上设备，并确认同意使用摄像头')
      }
    },
    destoryStop () {
      if (this.stream) {
        this.stream.getTracks().forEach(track => {
          track.stop()
        })
      }
    },
    // 加载设备
    loadDevices () {
      const _this = this
      if (!navigator.mediaDevices || !navigator.mediaDevices.enumerateDevices) {
        this.$message.warning('请检测是否插上设备，并确认同意使用摄像头')
      } else {
        navigator.mediaDevices.enumerateDevices().then(function (devices) {
          const list = []
          let videoIndex = 0
          devices.forEach(function (item, index) {
            if (item.kind === 'videoinput') {
              videoIndex++
              list.push({
                deviceId: item.deviceId,
                label: '摄像头' + videoIndex
              })
            }
          })
          _this.camera = list.length && list[0].deviceId
          _this.devicesList = list
        }).catch(function (err) {
          console.log(err.name + ':' + err.message)
        })
      }
    }
  }
}
</script>

<style lang="scss" scoped>
  #ActiveXDivOne {
    width: 100%;
    padding: 0 30px;
  }
  #camera-video {
    width: 100%;
    height: 300px;
  }
  .camera-button {
    width: 100%;
  }
</style>
